package com.jy.task.fileoper;

import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;

import com.hierynomus.msdtyp.AccessMask;
import com.hierynomus.msfscc.fileinformation.FileIdBothDirectoryInformation;
import com.hierynomus.mssmb2.SMB2CreateDisposition;
import com.hierynomus.mssmb2.SMB2ShareAccess;
import com.hierynomus.smbj.SMBClient;
import com.hierynomus.smbj.SmbConfig;
import com.hierynomus.smbj.auth.AuthenticationContext;
import com.hierynomus.smbj.connection.Connection;
import com.hierynomus.smbj.session.Session;
import com.hierynomus.smbj.share.DiskShare;
import com.hierynomus.smbj.share.File;
import com.jy.common.utils.base.Tools;
import com.jy.common.utils.base.UuidUtil;
import com.jy.entity.filemanager.TSFile;

public class TcpClient2 {
	private FTPClient ftp;

	private List<TSFile> fileStr;
	private String fileName;// 文件名
	private String extenName;// 扩展名
	private Date startDate;
	private Integer isSubFile;

	private String path;
	private String addr;
	private int port;
	private String username;
	private String password;

	private static DiskShare share;
	private static SMBClient client;

	private Date newDate;// 最新文件时间

	public TcpClient2(String fileName, String extenName, Date startDate,
			Integer isSubFile, String path, String addr, int prot,
			String username, String password) {
		fileStr = new ArrayList<TSFile>();
		this.fileName = fileName;
		this.extenName = extenName;
		this.startDate = startDate;
		this.isSubFile = isSubFile;
		this.path = path;
		this.addr = addr;
		this.port = prot;
		this.username = username;
		this.password = password;
	}

	/**
	 * 
	 * @param path
	 *            上传到ftp服务器哪个路径下
	 * @param addr
	 *            地址
	 * @param port
	 *            端口号
	 * @param username
	 *            用户名
	 * @param password
	 *            密码
	 * @return
	 * @throws Exception
	 */
	public boolean connect() throws Exception {
		boolean result = false;
		ftp = new FTPClient();
		int reply;
		ftp.connect(this.addr, this.port);
		ftp.login(username, password);
		ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
		reply = ftp.getReplyCode();
		if (!FTPReply.isPositiveCompletion(reply)) {
			ftp.disconnect();
			return result;
		}
		ftp.changeWorkingDirectory(this.path);
		ftp.enterLocalPassiveMode();
		ftp.setConnectTimeout(7200 * 1000);
		result = true;
		return result;
	}

	/**
	 * 判斷smb2 是否能连接
	 * 
	 * @return
	 */
	public boolean smb2Connect(String ip, String userNameString, String psw,
			String fileNameStr) {
		boolean result = false;
		// 设置超时时间(可选)
		SmbConfig config = SmbConfig.builder()
				.withTimeout(1200, TimeUnit.SECONDS)
				.withTimeout(1200, TimeUnit.SECONDS) // 超时设置读，写和Transact超时（默认为60秒）
				.withSoTimeout(1800, TimeUnit.SECONDS) // Socket超时（默认为0秒）
				.build();
		client = new SMBClient();
		try {
			Connection connection = client.connect(ip);
			AuthenticationContext ac = new AuthenticationContext(
					userNameString, psw.toCharArray(), ip);
			Session session = connection.authenticate(ac);
			share = (DiskShare) session.connectShare(fileNameStr);
			if (share.isConnected()) {
				result = true;
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}

	public boolean smbToSmbDirectory(String folder, String dstRoot) {
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
				"yyyy-MM-dd HH:mm:ss");
		boolean result = true;
		try {
			for (FileIdBothDirectoryInformation f : share.list(folder)) {
				if (f.getFileName().equals(".") || f.getFileName().equals("..")) {
					continue;
				}
				String filePath = folder + f.getFileName();
				String dstPath = dstRoot;
				if (share.fileExists(filePath)) {
					String dateTime = simpleDateFormat.format(f
							.getLastWriteTime().toDate());
					setNewDate(simpleDateFormat.parse(dateTime));
					// 文件時間是否在规定范围
					if (compareToDate(simpleDateFormat.parse(dateTime),
							simpleDateFormat.parse(simpleDateFormat
									.format(this.startDate)))) {
						if (!Tools.isEmpty(this.fileName)) {
							if (patternStr(f.getFileName())) {
								result = smbTosmb(filePath, dstPath,
										f.getFileName());
							}
						} else {
							result = smbTosmb(filePath, dstPath,
									f.getFileName());
						}

						if (!result) {
							boolean connFlg = false;
							Thread.sleep(5000);
							for (int i = 0; i < 3; i++) {
								connFlg = connect();
								// 休眠5秒
								Thread.sleep(5000);
								if (connFlg) {
									break;
								}
							}

							if (connFlg) {
								boolean newReturnFlag = smbTosmb(filePath,
										dstPath, f.getFileName());
								if (newReturnFlag) {
									continue;
								} else {
									result = false;
									break;
								}
							} else {
								result = false;
								break;
							}
						}

					}
				} else if (share.folderExists(filePath)) {
					if (this.isSubFile == 1) {
						smbToSmbDirectory(folder + f.getFileName() + "/",
								dstRoot + f.getFileName() + "/");
					}
				}
			}
		} catch (Exception e) {
			result = false;
			e.printStackTrace();

		} finally {
			// share.close();
			// share1.close();
			if (client != null) {
				client.close();
			}
		}
		return result;
	}

	public boolean smbTosmb(String filePath, String remoteUrl,
			String fielNameStr) {
		InputStream in = null;
		boolean uploadFlag = true;
		try {
			remoteUrl = new String(remoteUrl.getBytes("UTF-8"), "iso-8859-1");
			if (!ftp.isConnected()) {
				boolean connFlg = false;
				for (int i = 0; i < 10; i++) {
					connFlg = connect();
					// 休眠5秒
					Thread.sleep(5000);
					if (connFlg) {
						break;
					}
				}
				if (!ftp.isConnected())
					uploadFlag = false;
			}
			ftp.setControlEncoding("UTF-8");
			ftp.setFileType(FTP.BINARY_FILE_TYPE);
			CreateDirecroty(remoteUrl);
			// System.out.println(">>>1" + filePath);
			// System.out.println(">>>2" + remoteUrl);
			// System.out.println(">>>3" + fielNameStr);
			if (share.fileExists(filePath)) {
				File smbFileRead = share.openFile(filePath,
						EnumSet.of(AccessMask.GENERIC_READ), null,
						SMB2ShareAccess.ALL, SMB2CreateDisposition.FILE_OPEN,
						null);
				in = smbFileRead.getInputStream();
			}

			// boolean flag = ftp.changeWorkingDirectory(remoteUrl);
			// // System.out.println("localFile.getPath()" + remoteUrl);
			// if (!flag) {
			// // 创建上传的路径 该方法只能创建一级目录，在这里如果/home/ftpuser存在则可创建image
			// ftp.makeDirectory(remoteUrl);
			// ftp.changeWorkingDirectory(remoteUrl);
			// }
			fielNameStr = new String(fielNameStr.getBytes("UTF-8"),
					"iso-8859-1");
			if (ftp.isConnected()) {
				boolean typeflag = ftp.storeFile(fielNameStr, in);
				if (typeflag) {
					TSFile objFile = new TSFile();
					objFile.setId(UuidUtil.get32UUID());
					objFile.setFileName(fielNameStr);
					fileStr.add(objFile);
				}
			} else {
				return false;
			}
		} catch (Exception e) {
			closeFtp();
			uploadFlag = false;
			e.printStackTrace();
		} finally {
			try {
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return uploadFlag;

	}

	private boolean patternStr(String str) {
		String newString[] = (this.fileName).split(",");
		boolean rs = false;
		for (String reg : newString) {
			String regEx = reg.replace(".", "/").replace("?", ".?")
					.replace("*", ".*");
			Pattern pattern = Pattern.compile(regEx);
			Pattern pat = Pattern.compile(regEx, Pattern.CASE_INSENSITIVE);
			Matcher matcher = pattern.matcher(str);
			rs = matcher.find();
			if (rs)
				break;
		}
		// 查找字符串中是否有匹配正则表达式的字符/字符串
		return rs;
	}

	private boolean compareToDate(Date date1, Date date2) {
		if (date1.getTime() > date2.getTime()) {
			return true;
		}
		return false;
	}

	private void setNewDate(Date dateStr) {
		if (newDate != null) {
			if (compareToDate(dateStr, newDate)) {
				newDate = dateStr;
			}
		} else {
			newDate = dateStr;
		}
	}

	public Date getNewDate() {
		return newDate;
	}

	public List<TSFile> getFileList() {
		return fileStr;
	}

	public Map smbToftp(String folder, String dstRoot) {
		Map<String, Object> returnMap = new HashMap<String, Object>();
		boolean updateFlag = smbToSmbDirectory(folder, dstRoot);
		if (!updateFlag)
			newDate = null;
		// 上传失败
		if (!updateFlag) {
			returnMap.put("Msg", false);
		} else {
			returnMap.put("Msg", true);
		}
		return returnMap;
	}

	public boolean CreateDirecroty(String remote) throws IOException {
		boolean success = true;
		String directory = remote + "/";
		// String directory = remote.substring(0, remote.lastIndexOf("/") + 1);
		// 如果远程目录不存在，则递归创建远程服务器目录
		if (!directory.equalsIgnoreCase("/")
				&& !changeWorkingDirectory(new String(directory))) {
			int start = 0;
			int end = 0;
			if (directory.startsWith("/")) {
				start = 1;
			} else {
				start = 0;
			}
			end = directory.indexOf("/", start);
			String path = "";
			String paths = "";
			while (true) {
				String subDirectory = new String(remote.substring(start, end)
						.getBytes("UTF-8"), "iso-8859-1");
				path = path + "/" + subDirectory;
				if (!ftp.changeWorkingDirectory(path)) {
					if (makeDirectory(subDirectory)) {
						changeWorkingDirectory(subDirectory);
					} else {
						changeWorkingDirectory(subDirectory);
					}
				} else {
					changeWorkingDirectory(subDirectory);
				}
				paths = paths + "/" + subDirectory;
				start = end + 1;
				end = directory.indexOf("/", start);
				// 检查所有目录是否创建完毕
				if (end <= start) {
					break;
				}
			}
		}
		return success;
	}

	public boolean makeDirectory(String dir) {
		boolean flag = true;
		try {
			flag = ftp.makeDirectory(dir);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return flag;
	}

	// public boolean existFile(String path) throws IOException {
	// boolean flag = false;
	// FTPFile[] ftpFileArr = ftp.listFiles(path);
	// if (ftpFileArr.length > 0) {
	// flag = true;
	// }
	// return flag;
	// }

	public boolean changeWorkingDirectory(String directory) {
		boolean flag = true;
		try {
			flag = ftp.changeWorkingDirectory(directory);
		} catch (IOException ioe) {
			ioe.printStackTrace();
		}
		return flag;
	}

	public void closeFtp() {
		if (ftp != null && ftp.isConnected()) {
			try {
				ftp.logout();
				ftp.disconnect();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}
